Asp.net core 身份认证框架 Microsoft Identity的使用以及如何使用Idengtity创建自带的用户模型SignInManager和UserManager的使用等等 |
您所在的位置:网站首页 › jwt identity字段 › Asp.net core 身份认证框架 Microsoft Identity的使用以及如何使用Idengtity创建自带的用户模型SignInManager和UserManager的使用等等 |
要启动身份认证组件,首先要更改数据库上下文中继承的关系,原本我们是继承于 对于IdentityUser如果默认结构不能满足你的需求,你也可以通过继承IdentityUser去修改用户模型。 补充点:记得初始化构造函数 public AppDBcontext(DbContextOptions options) : base(options) { }好了,接着 在创建数据库之前,我们需要给框架注册服务认证的依赖。 我们找到Startup.cs文件 在ConfigureServices这个函数中添加函数依赖,代码如下: ///注册身份认证的服务依赖 ///泛型俩个参数分别是用户数据模型和角色模型 ///AddEntityFrameworkStores 通过这个函数连接数据库上下文对象 泛型为对应的上下文对象。 services.AddIdentity().AddEntityFrameworkStores();框架注入成功后,我们来进行数据更新。 这里使用.net 的命令进行数据迁移,不会数据迁移的请看这篇文章 在项目根目录下 进行CMD 输入一下命令 进行数据迁移 首先创建一个接收注册消息的Dto using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; namespace Fakexiecheng.API.Dtos { public class RegisterDto { [Required]//Required注释 为必填字段 public string Email { get; set; } [Required] public string Password { get; set; } [Required] [Compare(nameof(Password),ErrorMessage ="输入的密码不一致")] public string CofirmPassword { get; set; } } }接着我们在对应的Api里写好对应的注册函数 private readonly UserManager _userManager;//可以通过这个工具对密码进行加密 泛型为定义的用户模型 /// /// 用户注册 /// /// 注册信息 /// [AllowAnonymous] [HttpPost("register")] public async Task Register([FromBody] RegisterDto registerDto) { //1 使用用户名创建用户对象 var user = new IdentityUser() { UserName = registerDto.Email, Email = registerDto.Email }; //2 hash密码,保存用户 var result = await _userManager.CreateAsync(user, registerDto.Password);//hash密码并连同用户模型对象 一起保存打数据库中 //如果成功表示 用户创建成功并且保存起来了 //不成功 if (!result.Succeeded) { //返回400 return BadRequest(); } //3 return //成功 200 return Ok(); }其中hash密码的时候,我们用的Identity自带的工具 UserManager。代码中都有注释 自己看吧, 接着我们来试着用Postman进行请求一下。 首先用Identity框架下的SignInManager来处理用户登录验证,同时使用UserManager获取用户信息,并且提取用户权限,并转换为Claim使用JWT输出。 首先我们在控制器中注入服务依赖。 接下来我们使用SignInManager来进行用户验证, 登录方法中加入一下代码: [AllowAnonymous]//允许所有人访问 [HttpPost("login")] public async Task login([FromBody] LoginDto loginDto) { //1.进行信息认证 var loginResult = await _signInManager.PasswordSignInAsync(loginDto.Email,loginDto.password , false //指示在关闭浏览器后登录 Cookie 是否应该保留的标志。 , false//多次登录失败后 是否锁定账号 ); //判断是否验证成功 if (!loginResult.Succeeded) { // 400 return BadRequest(); } //获取用户信息 var user = await _userManager.FindByNameAsync(loginDto.Email); //2.创建JWT Token //header singningAlgorithm储存编码算法 var singningAlgorithm = SecurityAlgorithms.HmacSha256; //payload 需要用到的数据 var claims = new List { // sub ==jwt的ID //等同于 Sub:fake_user_id new Claim(JwtRegisteredClaimNames.Sub,user.Id), // new Claim(ClaimTypes.Role,"Admin")//角色信息 }; //获取用户角色 var roleNames = await _userManager.GetRolesAsync(user); //遍历角色 一个用户可能有多个角色 foreach (var roleName in roleNames) { var roleClaim = new Claim(ClaimTypes.Role, roleName); claims.Add(roleClaim); } //signature 数字签名 需要用到私钥 //私钥一般放在配置文件中 私钥是自定义的 想写什么写什么 //使用utf进行编码 var secretByte = Encoding.UTF8.GetBytes(_configuration["Authentication:SecretKey"]); //使用非对称算法 对私钥加密 var signingkey = new SymmetricSecurityKey(secretByte); //通过256验证非对称加密的私钥 var signingCredentials = new SigningCredentials(signingkey, singningAlgorithm); //创建token var token = new JwtSecurityToken( issuer:_configuration ["Authentication:Issuer"],//谁发布的TOken audience:_configuration["Authentication:Audience"],//token发布给谁 claims,//payload数据 notBefore:DateTime.UtcNow,//发布时间 expires:DateTime.UtcNow.AddDays(1),//有效时间 signingCredentials//数字签名 ); //以字符串形式 输出Token var tokenStr = new JwtSecurityTokenHandler().WriteToken(token); //3.返回jwt字符串 return Ok(tokenStr); }接下来我们来postman测试一下。 首先注册用户 然后用注册的用户登录系统 然后通过返回的JWT来进行一下数据访问 我们发现404 其实这里有个天大的坑。 原因:在我们使用Identity框架的多角色验证时,验证中间件使用的并不是JWT验证,和默认验证并不匹配。 解决办法 显示指定使用JWT 的验证方式。 再要访问的所有需要权限认证方法头部加上一下代码: [Authorize(AuthenticationSchemes = "Bearer")]接着测试一下 场景:当我们用的默认用户模型字段不够的时候,我么可以通过继承来定制一个用户模型。比如下图中
接着我们从代码的角度重载一下这几张表,首先新建一个ApplicationUser类继承IdentityUser,然后添加一下代码,这里切记 代码一定要一致,因为名称要和父类名称一致,不然会失败。 using Microsoft.AspNetCore.Identity; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Fakexiecheng.API.Models { public class ApplicationUser:IdentityUser { public string Address { get; set; } //shoppingCart //orders public virtual ICollection UserRoles { get; set; } public virtual ICollection Claims { get; set; } public virtual ICollection Logins { get; set; } public virtual ICollection Tokens { get; set; } } }然后我们把用到的IdentityUser全部替换为ApplicationUser 接着我们可以注入一下种子数据进行数据的更新、 接着我进入上下文关系文档,在OnModelCreating函数中进行种子数据的初始化。 添加如下代码: //初始化用户与角色的种子数据 //1.更新用户与角色的外键 //HasMany 表示一对多的关系 这个关系可以被映射为roles 每一个role都有一个外键关系 WithOne 而这个外键关系使用的是UserID 这个ID是必须的 所以加上IsRequired() modelBuilder.Entity(u => u.HasMany(x => x.UserRoles).WithOne().HasForeignKey(ur => ur.UserId).IsRequired()); //2.添加管理员角色 //给角色添加主键 var adminRoleId = Guid.NewGuid().ToString(); modelBuilder.Entity().HasData( new IdentityRole() { Id = adminRoleId, Name = "Admin", NormalizedName = "Admin".ToUpper()//大写 } ); //3.添加用户 var adminUserID = Guid.NewGuid().ToString(); ApplicationUser adminUser = new ApplicationUser { Id = adminUserID, UserName = "[email protected]", NormalizedUserName = "[email protected]".ToUpper(), Email= "[email protected]", NormalizedEmail= "[email protected]".ToUpper(), TwoFactorEnabled=false, EmailConfirmed=true, PhoneNumber="1234567891", PhoneNumberConfirmed=false }; //hash密码 var ph = new PasswordHasher(); adminUser.PasswordHash = ph.HashPassword(adminUser, "Fake123$"); modelBuilder.Entity().HasData(adminUser); //4.给用户加入管理员角色 modelBuilder.Entity().HasData(new IdentityUserRole(){ RoleId=adminRoleId, UserId=adminUserID });然后我们进行数据迁移。 我们发现可以成功登录并且创建数据。好了 就更新这么多了。。。。写的有点乱,希望不要介意。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |